package parsejson

import (
	"encoding/json"
	"errors"
	"fmt"
	"strings"
	"time"

	// "io/ioutil"
	"math/rand"
	// "os"
	"playbook/ginsvr/src/global"
	"playbook/ginsvr/src/projectmanagement"
	"strconv"

	"playbook/ginsvr/src/orm"
	"playbook/ginsvr/src/utils/fileutil"
	"playbook/ginsvr/src/utils/uuidutil"
)

type Cells struct {
	Cells []interface{} `json:"cells"`
}

// edge
type Edge struct {
	Shape  string   `json:"shape"`
	Id     string   `json:"id"`
	Source Source   `json:"source"`
	Target Target   `json:"target"`
	Data   EdgeData `json:"data"`
	Parent string   `json:"parent"`
}

type EdgeData struct {
	ActivityId   string        `json:"activityId"`
	ActivityName string        `json:"activityName"`
	Expresion    EdgeExpresion `json:"expression"`
	RuleTable    interface{}   `json:"ruleTable"`
	Seq          string        `json:"seq"`
}

type EdgeExpresion struct {
	ProjectId int64                  `json:"projectId"`
	RuleId    int64                  `json:"ruleId"`
	RuleName  string                 `json:"ruleName"`
	Version   string                 `json:"version"`
	IsValid   string                 `json:"isValid"`
	RootNode  map[string]interface{} `json:"rootNode"`
}

// edge-target
type Target struct {
	Cell string `json:"cell"`
	Port string `json:"port"`
}

// edge-source
type Source struct {
	Cell string `json:"cell"`
	Port string `json:"port"`
}

// circle
type Circle struct {
	Shape string     `json:"shape"`
	Id    string     `json:"id"`
	Data  CircleData `json:"data"`
}

type CircleData struct {
	Type                 string        `json:"type"`
	Id                   string        `json:"id"`
	Name                 string        `json:"name"`
	Overtime             string        `json:"overtime"`
	Version              string        `json:"version"`
	OrchestraTransaction bool          `json:"orchestraTransaction"`
	InputParameter       []interface{} `json:"input-parameter"`
	OutputParameter      []interface{} `json:"output-parameter"`
	OutputContext        string        `json:"output-context"`
	Desc                 string        `json:"desc"`
	Projectid            string        `json:"projectid"`
}

// type Parameter struct {
// 	Name     string        `json:"name"`
// 	Type     string        `json:"type"`
// 	Optional string        `json:"classPath"`
// 	para     []interface{} `json:"parameter"`
// }

// rect
type Rect struct {
	Shape  string                 `json:"shape"`
	Id     string                 `json:"id"`
	Alias  string                 `json:"alias"`
	Data   map[string]interface{} `json:"data"`
	Parent string                 `json:"parent"`
}

// Process
type Process struct {
	Id                   string                   `json:"id"`
	Projectid            string                   `json:"projectid"`
	Name                 string                   `json:"name"`
	Overtime             string                   `json:"overtime"`
	Version              string                   `json:"version"`
	OrchestraTransaction bool                     `json:"orchestraTransaction"`
	InputParameter       map[string]interface{}   `json:"input-parameter"`
	OutputParameter      map[string]interface{}   `json:"output-parameter"`
	OutputContext        string                   `json:"output-context"`
	Activities           map[string][]interface{} `json:"activities"`
	FistTransion         []interface{}            `json:"first-transition"`
	Desc                 string                   `json:"desc"`
}

type FullProcess struct {
	Process Process `json:"process"`
}

type SaveDate struct {
	Cells     []interface{} `json:"cells"`
	Isprocess bool          `json:"isprocess"`
}

func SaveAllProcess(cells []interface{}, isprocess bool) interface{} {
	if isprocess {
		return SaveProcess(cells)
	} else {
		return SaveSubProcess(cells)
	}
}

func SaveSubProcess(cells []interface{}) interface{} {
	SaveOriginJson(cells, false)

	processJson, err := processOriginJson(cells)
	if err != nil {
		genebeanmsg := make(map[string]interface{})
		genebeanmsg["respCode"] = "000003"
		genebeanmsg["respMsg"] = err.Error()
		return genebeanmsg
	}
	var ormFullProcess orm.FullProcess
	json.Unmarshal(processJson, &ormFullProcess)

	sub := orm.FullSubProcess{
		SubProcess: ormFullProcess.Process,
	}
	SaveSubProcessJson(sub)
	return orm.UpdateSubprocess(sub)
}

/**
* 拼接json路径
 */
func GetJsonPath(projectid interface{}, isSubprocess bool) (gsd orm.GeneSrcDefine) {
	res := orm.GetGeneSrcDefine("composejson")
	srcpath := res.Srcpath
	// if isSubprocess {
	// 	srcpath = srcpath + global.PTHSEP + "subprocess"
	// }
	if projectid != nil && projectid.(string) != "" {
		projectpath := projectmanagement.GetProjectPathById(projectid.(string)).(map[string]interface{})
		if projectpath["projectpath"] != nil {
			//项目名称：fins
			//json路径：cbcbp-fins/cbcbp-fins-boot/resources/...
			srcpath = projectpath["projectpath"].(string) + global.PTHSEP + "cbcbp-" + projectpath["projectname"].(string) +
				global.PTHSEP + "cbcbp-" + projectpath["projectname"].(string) + "-boot" + global.PTHSEP + srcpath
		}
	}
	res.Srcpath = srcpath
	return res
}

/**
* 保存子流程json文件
 */
func SaveSubProcessJson(fullSubProcess orm.FullSubProcess) {
	processJson, _ := json.MarshalIndent(fullSubProcess, "", "\t")
	srcpath := GetJsonPath(fullSubProcess.SubProcess.Projectid, true).Srcpath

	createDirPath := srcpath + global.PTHSEP + fullSubProcess.SubProcess.Name
	standardName := fullSubProcess.SubProcess.Name + ".json"
	fileutil.GetClearFile(createDirPath, standardName)

	standardJsonPath := srcpath + global.PTHSEP + fullSubProcess.SubProcess.Name + global.PTHSEP + fullSubProcess.SubProcess.Name + ".json"
	var strlstStandard []string
	strlstStandard = append(strlstStandard, string(processJson))

	fileutil.Filewrite(standardJsonPath, strlstStandard)
}

func SaveProcess(cells []interface{}) interface{} {
	SaveOriginJson(cells, true)

	processJson, err := processOriginJson(cells)
	if err != nil {
		genebeanmsg := make(map[string]interface{})
		genebeanmsg["respCode"] = "000003"
		genebeanmsg["respMsg"] = err.Error()
		return genebeanmsg
	}
	var ormFullProcess orm.FullProcess
	json.Unmarshal(processJson, &ormFullProcess)
	//写出文件
	//标准
	srcpath := GetJsonPath(ormFullProcess.Process.Projectid, false).Srcpath

	createDirPath := srcpath + global.PTHSEP + ormFullProcess.Process.Name
	standardName := ormFullProcess.Process.Name + ".json"
	fileutil.GetClearFile(createDirPath, standardName)

	standardJsonPath := srcpath + global.PTHSEP + ormFullProcess.Process.Name + global.PTHSEP + ormFullProcess.Process.Name + ".json"
	var strlstStandard []string
	strlstStandard = append(strlstStandard, string(processJson))

	fileutil.Filewrite(standardJsonPath, strlstStandard)

	return orm.UpdateProcess(ormFullProcess)
}

func SaveOriginJson(cells []interface{}, isprocess bool) {
	var processName string
	var projectId string
	var cell Cells
	cell.Cells = cells
	cellsJson, _ := json.MarshalIndent(cell, "", "\t")
	for _, cell := range cells {

		if eachMap, ok := cell.(map[string]interface{}); ok {

			if eachMap["shape"] == "image" {

				var circleStruct Circle
				temp, _ := json.Marshal(cell)
				json.Unmarshal(temp, &circleStruct)
				if circleStruct.Data.Type == "Start" {
					processName = circleStruct.Data.Name
					projectId = circleStruct.Data.Projectid
					break
				}
			}
		}
	}

	srcpath := GetJsonPath(projectId, !isprocess).Srcpath

	createDirPath := srcpath + global.PTHSEP + processName
	originName := "origin.json"
	fileutil.GetClearFile(createDirPath, originName)

	originJsonPath := srcpath + global.PTHSEP + processName + global.PTHSEP + "origin.json"
	var strlstOrigin []string
	strlstOrigin = append(strlstOrigin, string(cellsJson))
	fileutil.Filewrite(originJsonPath, strlstOrigin)
}

func DownloadJson(cells []interface{}) interface{} {
	var cell Cells
	cell.Cells = cells
	processJson, _ := processOriginJson(cells)
	var ormFullProcess orm.FullProcess
	json.Unmarshal(processJson, &ormFullProcess)
	orm.UpdateProcess(ormFullProcess)
	return ormFullProcess
}

// json处理主逻辑
func processOriginJson(cells []interface{}) ([]byte, error) {
	// 定义返回json
	var process Process
	//定义顺序存储map
	edgeMap := make(map[string]Edge)
	//定义原子存储map
	rectMap := make(map[string]map[string]interface{})
	//定义循环原子存储map
	loopMap := make(map[string]string)
	//原子uuidcd
	activityIdMap := make(map[string]string)
	//原子别名校验map
	aliasMap := make(map[string]bool)
	//原子別名-原子id
	activityAliasMap := make(map[string]string)

	var startId string
	var endId string
	var processId string
	edgeSourceNum := 0

	rand.Seed(time.Now().UnixNano())

	for _, cell := range cells {

		if eachMap, ok := cell.(map[string]interface{}); ok {

			switch eachMap["shape"] {
			case "image":
				var circleStruct Circle
				//转存circle结构体
				temp, _ := json.Marshal(cell)
				json.Unmarshal(temp, &circleStruct)
				if circleStruct.Data.Type == "Start" {
					startId = circleStruct.Id
					processId = circleStruct.Data.Id
					activityIdMap[startId] = processId
					activityAliasMap["Start"] = processId
					process = addInputPara(process, circleStruct, processId)
				} else {
					endId = circleStruct.Id
					process = addOutputPara(process, circleStruct)
				}

			case "atom-node", "loop-rect", "script-rect", "subprocess-node":
				var recStruct Rect
				var alias string
				rectUUId := "a" + uuidutil.GetUUID()
				//转存rect结构体
				temp, _ := json.Marshal((cell))
				json.Unmarshal(temp, &recStruct)
				// fmt.Println(recStruct)

				//检查别名是否重复
				if recStruct.Data["alias"] != nil {
					alias = recStruct.Data["alias"].(string)
					if aliasMap[alias] {
						return nil, errors.New("别名重复")
					} else {
						aliasMap[alias] = true
					}
				}

				//结构体放入map
				rectMap[recStruct.Id] = recStruct.Data
				activityIdMap[recStruct.Id] = rectUUId
				activityAliasMap[alias] = rectUUId

				//如果是子流程，activityid需要设置成子流程的id
				if recStruct.Data["type"].(float64) == 3 && recStruct.Data["id"] != nil {
					activityIdMap[recStruct.Id] = recStruct.Data["id"].(string)
				}

				//循环map字典 key子id-value父id
				if recStruct.Parent != "" {
					loopMap[recStruct.Id] = recStruct.Parent
				}

			case "edge":
				var edgeStruct Edge
				//转存edge结构体
				temp, _ := json.Marshal(cell)
				json.Unmarshal(temp, &edgeStruct)
				source := edgeStruct.Source
				edgeMap[strconv.FormatInt(int64(edgeSourceNum), 10)+"."+source.Cell] = edgeStruct
				edgeSourceNum++
			}
		}
	}
	if startId == "" || endId == "" {
		return nil, errors.New("编排缺少start或end")
	}
	edgeErr := checkEdge(edgeMap, rectMap, startId, endId)
	if edgeErr != nil {
		return nil, edgeErr
	}

	activityIdMap[endId] = processId
	activityAliasMap["End"] = processId

	process.FistTransion = addFirstTransion(edgeMap, startId, activityIdMap, activityAliasMap)
	process, err := addActivity(edgeMap, rectMap, process, activityIdMap, endId, loopMap, activityAliasMap)
	if err != nil {
		return nil, err
	}
	process = changeParamPath(process)

	var fullprocess FullProcess
	fullprocess.Process = process
	processJson, _ := json.MarshalIndent(fullprocess, "", "\t")
	return processJson, err

}

func checkEdge(edgeMap map[string]Edge, rectMap map[string]map[string]interface{}, startId string, endId string) error {
	startEdgeIsExist := false
	endEdgeIsExist := false
	for _, edge := range edgeMap {
		edgeSource := edge.Source.Cell
		edgeTarget := edge.Target.Cell
		if startId == edgeSource {
			startEdgeIsExist = true
		}
		if endId == edgeTarget {
			endEdgeIsExist = true
		}
	}
	if !startEdgeIsExist {
		return errors.New("start缺少必要连线")
	}
	if !endEdgeIsExist {
		return errors.New("end缺少必要连线")
	}
	for rectId, rectData := range rectMap {
		rectEdgeIsExist := false
		for _, edge := range edgeMap {
			edgeSource := edge.Source.Cell
			edgeTarget := edge.Target.Cell
			if rectId == edgeSource || rectId == edgeTarget {
				rectEdgeIsExist = true
				break
			}
		}
		if !rectEdgeIsExist {
			rectName := rectData["name"].(string)
			return errors.New(rectName + "缺少必要连线")
		}
	}
	return nil
}

// 添加原子
func addActivity(edgeMap map[string]Edge, rectMap map[string]map[string]interface{}, process Process,
	activityIdMap map[string]string, endId string, loopMap map[string]string, activityAliasMap map[string]string) (Process, error) {
	var activity []interface{}
	activities := make(map[string][]interface{})

	//遍历原子map
	if len(rectMap) != 0 {
		for rectId, rectData := range rectMap {
			var transion []interface{}
			//遍历边map添加transion
			if len(edgeMap) != 0 {
				for edgeSource, edge := range edgeMap {
					//找出与原子id一致的边
					edgeSource = strings.SplitAfter(edgeSource, ".")[1]
					if rectData["type"].(float64) == 1 {
						if rectId == edgeSource && edge.Parent == "" {
							if edge.Data.ActivityName != "" {
								rootNode := edge.Data.Expresion.RootNode

								rootNode = changeTransitionLeftContent(rootNode, activityAliasMap)

								edge.Data.Expresion.RootNode = rootNode
								//设置ruleId
								edge.Data.Expresion.RuleId = rand.Int63()
								//设置分支id
								edge.Data.ActivityId = activityIdMap[edge.Target.Cell]
								transion = append(transion, edge.Data)
							} else {
								transionMap := make(map[string]string)
								if edge.Target.Cell != endId {
									transionMap["activityId"] = activityIdMap[edge.Target.Cell]
									transion = append(transion, transionMap)
								}
							}

						}
					} else {
						if rectId == edgeSource {
							if edge.Data.ActivityName != "" {
								rootNode := edge.Data.Expresion.RootNode

								rootNode = changeTransitionLeftContent(rootNode, activityAliasMap)

								edge.Data.Expresion.RootNode = rootNode
								//设置ruleId
								edge.Data.Expresion.RuleId = rand.Int63()
								//设置分支id
								edge.Data.ActivityId = activityIdMap[edge.Target.Cell]
								transion = append(transion, edge.Data)
							} else {
								transionMap := make(map[string]string)
								if edge.Target.Cell != endId {
									transionMap["activityId"] = activityIdMap[edge.Target.Cell]
									transion = append(transion, transionMap)
								}
							}

						}
					}

				}
			}
			rectData["transition"] = transion
			//设置activity-id
			rectData["id"] = activityIdMap[rectId]
			rectData["originId"] = rectId
			rectData = changeActivityDataName(rectData, process.Name)
			rectData = changeRetryTransition(rectData, activityAliasMap)
			activity = append(activity, rectData)
		}
	}

	activity, err := changeActivityMapping(activity, activityAliasMap)
	if err != nil {
		return process, err
	}
	activity = processLoop(activity, loopMap, edgeMap, activityIdMap, activityAliasMap)
	activities["activity"] = activity
	process.Activities = activities
	return process, nil
}

// 添加input-parameter
func addInputPara(process Process, circleStruct Circle, processId string) Process {
	process.Id = processId
	process.Name = circleStruct.Data.Name
	process.Version = circleStruct.Data.Version
	process.Overtime = circleStruct.Data.Overtime
	process.OutputContext = circleStruct.Data.OutputContext
	process.Desc = circleStruct.Data.Desc
	process.OrchestraTransaction = circleStruct.Data.OrchestraTransaction
	process.Projectid = circleStruct.Data.Projectid

	inputParameter := circleStruct.Data.InputParameter
	var temp map[string]interface{}
	if len(inputParameter) != 0 {
		temp = convertParameter(inputParameter[0].(map[string]interface{}))
	}
	inputParameterMap := make(map[string]interface{})
	inputParameterMap["parameter"] = temp
	process.InputParameter = inputParameterMap
	return process
}

// 添加output-parameter
func addOutputPara(process Process, circleStruct Circle) Process {
	outputParameter := circleStruct.Data.OutputParameter
	var temp map[string]interface{}
	if len(outputParameter) != 0 {
		temp = convertParameter(outputParameter[0].(map[string]interface{}))
	}
	outputParameterMap := make(map[string]interface{})
	outputParameterMap["parameter"] = temp
	process.OutputParameter = outputParameterMap
	return process
}

// 添加first-transion
func addFirstTransion(edgeMap map[string]Edge, startId string, activityIdMap map[string]string, activityAliasMap map[string]string) []interface{} {
	var transion []interface{}
	if len(edgeMap) != 0 {
		for edgeSource, edge := range edgeMap {
			//找出与原子id一致的边
			edgeSource = strings.SplitAfter(edgeSource, ".")[1]
			if startId == edgeSource {
				if edge.Data.ActivityName != "" {
					rootNode := edge.Data.Expresion.RootNode
					rootNode = changeTransitionLeftContent(rootNode, activityAliasMap)
					edge.Data.Expresion.RootNode = rootNode
					//设置分支id
					edge.Data.ActivityId = activityIdMap[edge.Target.Cell]
					//设置ruleId
					edge.Data.Expresion.RuleId = rand.Int63()
					transion = append(transion, edge.Data)
				} else {
					transionMap := make(map[string]string)
					transionMap["activityId"] = activityIdMap[edge.Target.Cell]
					transion = append(transion, transionMap)
				}
			}

		}
	}
	return transion
}

// 递归修改parameter结构
func convertParameter(parameterMap map[string]interface{}) map[string]interface{} {
	parameterType := parameterMap["type"]
	fmt.Println(parameterType)
	if parameterType == "List" {
		if parameterMap["parameter"] == nil {
			return parameterMap
		}
		subParam := parameterMap["parameter"].([]interface{})
		subParamMap := subParam[0].(map[string]interface{})
		parameterMap["parameter"] = subParamMap
		convertParameter(subParamMap)
	} else if parameterType == "Map" {
		if parameterMap["parameter"] == nil {
			return parameterMap
		}
		subParam := parameterMap["parameter"].([]interface{})
		for _, value := range subParam {
			subParamElement := value.(map[string]interface{})
			convertParameter(subParamElement)
		}
	}
	return parameterMap
}

func changeActivityMapping(activity []interface{}, activityAliasMap map[string]string) ([]interface{}, error) {
	if len(activity) != 0 {
		for index, value := range activity {
			activityMap := value.(map[string]interface{})
			activityId := activityMap["id"].(string)
			activityName := activityMap["name"].(string)
			//input-parameter-mapping
			if activityMap["input-parameter-mapping"] != nil {
				inputParameterMapping := activityMap["input-parameter-mapping"].(map[string]interface{})
				inputMessageBeanMapping := inputParameterMapping["massage-bean-mapping"].(map[string]interface{})
				inputMessageBeanMapping, err := changeInputMapping(inputMessageBeanMapping, activityId, activityAliasMap)
				if err != nil {
					return nil, errors.New(activityName + "缺少入参参数映射")
				}
				inputParameterMapping["massage-bean-mapping"] = inputMessageBeanMapping
				activityMap["input-parameter-mapping"] = inputParameterMapping
			}

			//loop-input-parameter-mapping
			if activityMap["loop-input-parameter-mapping"] != nil {
				inputParameterMapping := activityMap["loop-input-parameter-mapping"].(map[string]interface{})
				inputMessageBeanMapping := inputParameterMapping["massage-bean-mapping"].(map[string]interface{})
				inputMessageBeanMapping, err := changeInputMapping(inputMessageBeanMapping, activityId, activityAliasMap)
				if err != nil {
					return nil, errors.New(activityName + "缺少循环体入参参数映射")
				}
				inputParameterMapping["massage-bean-mapping"] = inputMessageBeanMapping
				activityMap["loop-input-parameter-mapping"] = inputParameterMapping
			}

			//output-parameter-mapping
			if activityMap["output-parameter-mapping"] != nil {
				outputParameterMapping := activityMap["output-parameter-mapping"].(map[string]interface{})
				outputMessageBeanMapping := outputParameterMapping["massage-bean-mapping"].(map[string]interface{})
				outputMessageBeanMapping, err := changeOutputMapping(outputMessageBeanMapping, activityId, activityAliasMap)
				if err != nil {
					return nil, errors.New(activityName + "缺少出参参数映射")
				}
				outputParameterMapping["massage-bean-mapping"] = outputMessageBeanMapping
				activityMap["output-parameter-mapping"] = outputParameterMapping
			}

			//loop-output-parameter-mapping
			if activityMap["loop-output-parameter-mapping"] != nil {
				outputParameterMapping := activityMap["loop-output-parameter-mapping"].(map[string]interface{})
				outputMessageBeanMapping := outputParameterMapping["massage-bean-mapping"].(map[string]interface{})
				outputMessageBeanMapping, err := changeOutputMapping(outputMessageBeanMapping, activityId, activityAliasMap)
				if err != nil {
					return nil, errors.New(activityName + "缺少循环体出参参数映射")
				}
				outputParameterMapping["massage-bean-mapping"] = outputMessageBeanMapping
				activityMap["loop-output-parameter-mapping"] = outputParameterMapping

			}

			activity[index] = activityMap
		}
	}

	return activity, nil
}

func changeInputMapping(messageBeanMapping map[string]interface{}, activityId string, activityAliasMap map[string]string) (map[string]interface{}, error) {
	mapping := messageBeanMapping["mapping"]
	mappingArray := mapping.([]interface{})
	for index, mappingValue := range mappingArray {
		mappingMap := mappingValue.(map[string]interface{})
		var fromStr string
		var toStr string
		from := mappingMap["from"]
		to := mappingMap["to"]
		mappingType := mappingMap["type"]
		if from == "" && to != "" && mappingType.(string) == "value-mapping" {
			return nil, errors.New("inputMapping error")
		}
		if from != "" {
			fromArray := strings.SplitAfter(from.(string), ".")
			rectFromAlias := strings.TrimSuffix(fromArray[1], ".")
			activityFromId := activityAliasMap[rectFromAlias]
			fromArray[1] = activityFromId + "."
			for i := 1; i < len(fromArray); i++ {
				fromStr = fromStr + fromArray[i]
			}
			//删除list映射结尾的括号
			mappingMap["from"] = fromStr
		}

		if to != "" {
			toArray := strings.SplitAfter(to.(string), ".")
			for i := 0; i < len(toArray); i++ {
				toStr = toStr + toArray[i]
			}
			toStr = activityId + "." + toStr
			mappingMap["to"] = toStr
		}

		mappingArray[index] = mappingMap

	}
	mapping = mappingArray
	messageBeanMapping["mapping"] = mapping
	return messageBeanMapping, nil
}

func changeOutputMapping(messageBeanMapping map[string]interface{}, activityId string, activityAliasMap map[string]string) (map[string]interface{}, error) {
	mapping := messageBeanMapping["mapping"]
	mappingArray := mapping.([]interface{})
	for index, mappingValue := range mappingArray {
		mappingMap := mappingValue.(map[string]interface{})
		var fromStr string
		var toStr string
		from := mappingMap["from"]
		to := mappingMap["to"]
		mappingType := mappingMap["type"]
		if from == "" && to != "" && mappingType.(string) == "value-mapping" {
			return nil, errors.New("outputmapping error")
		}

		if from != "" {
			fromArray := strings.SplitAfter(from.(string), ".")
			for i := 0; i < len(fromArray); i++ {
				fromStr = fromStr + fromArray[i]
			}
			fromStr = activityId + "." + fromStr
			mappingMap["from"] = fromStr

		}

		if to != "" {
			toArray := strings.SplitAfter(to.(string), ".")
			rectToAlias := strings.TrimSuffix(toArray[1], ".")
			activityToId := activityAliasMap[rectToAlias]
			toArray[1] = activityToId + "."
			for i := 1; i < len(toArray); i++ {
				toStr = toStr + toArray[i]
			}
			mappingMap["to"] = toStr
		}

		mappingArray[index] = mappingMap
	}
	mapping = mappingArray
	messageBeanMapping["mapping"] = mapping
	return messageBeanMapping, nil
}

func changeParamPath(process Process) Process {
	srcpath := orm.GetGeneSrcDefine("composebean").Srcpath
	srcpath = "com" + "\\" + strings.Split(srcpath, "com\\")[1] + "\\" + process.Name
	srcpath = strings.Replace(srcpath, "\\", ".", -1)

	inputParameter := process.InputParameter
	if inputParameter["parameter"] != nil {
		parameterin := inputParameter["parameter"].(map[string]interface{})
		parameterArray := parameterin["parameter"].([]interface{})
		if len(parameterArray) != 0 {
			for index, value := range parameterArray {
				paramMap := value.(map[string]interface{})
				name := paramMap["name"].(string)
				if name == "data" {
					paramMap["classPath"] = srcpath + "." + strings.ToUpper(process.Name[:1]) + process.Name[1:] + "In"
				}
				parameterArray[index] = paramMap
			}
		}
		parameterin["parameter"] = parameterArray
		inputParameter["parameter"] = parameterin
		process.InputParameter = inputParameter
	}

	outputParameter := process.OutputParameter
	if outputParameter["parameter"] != nil {
		parameterout := outputParameter["parameter"].(map[string]interface{})
		parameterArray := parameterout["parameter"].([]interface{})
		if len(parameterArray) != 0 {
			for index, value := range parameterArray {
				paramMap := value.(map[string]interface{})
				name := paramMap["name"].(string)
				if name == "data" {
					paramMap["classPath"] = srcpath + "." + strings.ToUpper(process.Name[:1]) + process.Name[1:] + "Out"
				}
				parameterArray[index] = paramMap
			}
		}
		parameterout["parameter"] = parameterArray
		outputParameter["parameter"] = parameterout
		process.OutputParameter = outputParameter
	}

	return process
}

func changeActivityDataName(rectData map[string]interface{}, processName string) map[string]interface{} {
	isScript := false
	if rectData["type"].(float64) == 2 {
		isScript = true
	}
	if rectData["type"].(float64) == 3 {
		return rectData
	}
	if rectData["input-parameter"] != nil {
		inputParameter := rectData["input-parameter"].(map[string]interface{})
		rectData["input-parameter"] = changeParameterDataName(inputParameter, processName, "In", isScript)
	}

	if rectData["output-parameter"] != nil {
		outputParameter := rectData["output-parameter"].(map[string]interface{})
		rectData["output-parameter"] = changeParameterDataName(outputParameter, processName, "Out", isScript)
	}

	return rectData

}

func changeParameterDataName(parameterOuter map[string]interface{}, processName string, inOrOut string, isScript bool) map[string]interface{} {
	srcpath := orm.GetGeneSrcDefine("composebean").Srcpath
	srcpath = "com" + "\\" + strings.Split(srcpath, "com\\")[1] + "\\" + processName
	srcpath = strings.Replace(srcpath, "\\", ".", -1)

	parameterInner := parameterOuter["parameter"].(map[string]interface{})
	parameterArray := parameterInner["parameter"].([]interface{})
	parameterDataIsExist := false
	for index, value := range parameterArray {
		valueMap := value.(map[string]interface{})
		if valueMap["type"] == "Map" {
			valueMap["name"] = "data"
			if isScript {
				valueMap["classPath"] = srcpath + "." + strings.ToUpper(processName[:1]) + processName[1:] + inOrOut
			}
			parameterDataIsExist = true
			parameterArray[index] = valueMap
		}
	}
	if !parameterDataIsExist {
		parameterMap := make(map[string]interface{})
		parameterMap["classPath"] = ""
		parameterMap["name"] = "data"
		parameterMap["type"] = "Map"
		var array []interface{}
		parameterMap["parameter"] = array
		parameterArray = append(parameterArray, parameterMap)
	}
	parameterInner["parameter"] = parameterArray
	parameterOuter["parameter"] = parameterInner
	return parameterOuter
}

func changeTransitionLeftContent(rootNode map[string]interface{}, activityAliasMap map[string]string) map[string]interface{} {
	children := rootNode["children"].([]interface{})
	if len(children) == 0 {
		return rootNode
	}
	childrenMap := children[0].(map[string]interface{})
	childrenMap = changeTransitionLeftContent(childrenMap, activityAliasMap)
	childrenMap = changeLeftContent(childrenMap, activityAliasMap)
	if childrenMap["rightContentType"] != nil && childrenMap["rightContentType"].(string) == "变量" {
		childrenMap = changeRightContent(childrenMap, activityAliasMap)
	}

	exetraRulesArray := childrenMap["extraRules"].([]interface{})
	for index, value := range exetraRulesArray {
		exetraRules := value.(map[string]interface{})
		exetraRules = changeLeftContent(exetraRules, activityAliasMap)
		if exetraRules["rightContentType"] != nil && exetraRules["rightContentType"].(string) == "变量" {
			exetraRules = changeRightContent(exetraRules, activityAliasMap)
		}
		exetraRulesArray[index] = exetraRules
	}
	childrenMap["extraRules"] = exetraRulesArray
	children[0] = childrenMap
	rootNode["children"] = children
	return rootNode
}

func changeLeftContent(node map[string]interface{}, activityAliasMap map[string]string) map[string]interface{} {
	leftContent := node["leftContent"].(string)
	if leftContent == "out2" {
		return node
	}
	leftContentArray := strings.SplitAfter(leftContent, ".")
	var strLeftContent string
	for index, value := range leftContentArray {
		if index == 1 {
			strLeftContent = activityAliasMap[strings.Trim(leftContentArray[1], ".")] + "."
		}
		if index > 1 {
			strLeftContent = strLeftContent + value
		}
	}
	node["leftContent"] = strLeftContent
	return node
}

func changeRightContent(node map[string]interface{}, activityAliasMap map[string]string) map[string]interface{} {
	rightContent := node["rightContent"].(string)
	rightContentArray := strings.SplitAfter(rightContent, ".")
	var strRightContent string
	for index, value := range rightContentArray {
		if index == 1 {
			strRightContent = activityAliasMap[strings.Trim(rightContentArray[1], ".")] + "."
		}
		if index > 1 {
			strRightContent = strRightContent + value
		}
	}
	node["rightContent"] = strRightContent
	return node
}

func processLoop(activity []interface{}, loopMap map[string]string, edgeMap map[string]Edge, activityIdMap map[string]string, activityAliasMap map[string]string) []interface{} {
	var deleteIndexArray []int
	var newActivity []interface{}
	for outerIndex, outerValue := range activity {
		outerActivityMap := outerValue.(map[string]interface{})
		if outerActivityMap["type"].(float64) == 1 {
			var loopFirstTransition []interface{}
			var loopActivity []interface{}
			loopActivities := make(map[string]interface{})
			loopId := outerActivityMap["originId"].(string)
			for index, innerValue := range activity {
				innerActivityMap := innerValue.(map[string]interface{})
				chiledrenId := innerActivityMap["originId"].(string)
				if loopMap[chiledrenId] == loopId {
					loopActivity = append(loopActivity, innerActivityMap)
					deleteIndexArray = append(deleteIndexArray, index)
				}
			}
			loopActivities["activity"] = loopActivity
			outerActivityMap["activities"] = loopActivities

			loopFirstTransition = addLoopFirstTransion(edgeMap, loopId, activityIdMap, activityAliasMap)
			outerActivityMap["first-transition"] = loopFirstTransition

			activity[outerIndex] = outerActivityMap
		}
	}
	for index, value := range activity {
		isDelete := false
		for _, deleteIndex := range deleteIndexArray {
			if index == deleteIndex {
				isDelete = true
				break
			}
		}
		if !isDelete {
			newActivity = append(newActivity, value)
		}
	}
	return newActivity
}

// 添加first-transion
func addLoopFirstTransion(edgeMap map[string]Edge, loopId string, activityIdMap map[string]string, activityAliasMap map[string]string) []interface{} {
	var transion []interface{}
	if len(edgeMap) != 0 {
		for edgeSource, edge := range edgeMap {
			//找出与原子id一致的边
			edgeSource = strings.SplitAfter(edgeSource, ".")[1]
			if edge.Parent == loopId && loopId == edgeSource {
				if edge.Data.ActivityName != "" {
					rootNode := edge.Data.Expresion.RootNode
					rootNode = changeTransitionLeftContent(rootNode, activityAliasMap)
					edge.Data.Expresion.RootNode = rootNode
					//设置分支id
					edge.Data.ActivityId = activityIdMap[edge.Target.Cell]
					//设置ruleId
					edge.Data.Expresion.RuleId = rand.Int63()

					transion = append(transion, edge.Data)
				} else {
					transionMap := make(map[string]string)
					transionMap["activityId"] = activityIdMap[edge.Target.Cell]
					transion = append(transion, transionMap)
				}
			}

		}
	}
	return transion
}

func changeRetryTransition(rectData map[string]interface{}, activityAliasMap map[string]string) map[string]interface{} {
	if rectData["retry-transition"] == nil {
		return rectData
	}
	retryTransition := rectData["retry-transition"].([]interface{})
	if len(retryTransition) == 0 {
		return rectData
	}
	for index, edge := range retryTransition {
		edge := edge.(map[string]interface{})
		edge["ruleId"] = rand.Int63()
		rootNode := edge["rootNode"].(map[string]interface{})
		edge["rootNode"] = changeTransitionLeftContent(rootNode, activityAliasMap)
		retryTransition[index] = edge
	}
	rectData["retry-transition"] = retryTransition
	return rectData
}
